from flask import request, jsonify, g, current_app
from flask_jwt_extended import jwt_required
import datetime
import random
import logging
from bson import ObjectId

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required, hash_password
from app.schemas.doctor import DoctorSchema, DoctorUpdateSchema
from app.utils.common import normalize_data, paginate, generate_id

# 配置日志
logger = logging.getLogger(__name__)

@api_bp.route('/doctors', methods=['GET'])
@jwt_required()
@permission_required('doctor:read')
def get_doctors():
    """获取医生列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'name')
    order = request.args.get('order', 'asc')
    
    # 构建查询条件
    query = {}
    
    # 按姓名搜索
    name = request.args.get('name')
    if name:
        query['name'] = {'$regex': name, '$options': 'i'}
    
    # 按科室筛选
    department_id = request.args.get('departmentId')
    if department_id:
        query['departmentId'] = department_id
    
    # 按职称筛选
    title = request.args.get('title')
    if title:
        query['title'] = title
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 按专长筛选
    specialty = request.args.get('specialty')
    if specialty:
        query['specialties'] = specialty
    
    # 按用户ID筛选（新增）
    user_id = request.args.get('userId')
    if user_id:
        print(f"=== 通过userId查询医生开始 ===")
        print(f"请求的userId: {user_id}")
        
        # 先打印所有医生，看看userId字段是什么样的
        all_doctors = list(mongo.db.doctors.find())
        print(f"数据库中共有 {len(all_doctors)} 个医生")
        for doc in all_doctors:
            print(f"医生: {doc.get('name')}, userId类型: {type(doc.get('userId'))}, userId值: {doc.get('userId')}")
        
        # 尝试多种查询方式
        # 1. 直接查询字符串
        doctor = mongo.db.doctors.find_one({'userId': user_id})
        if doctor:
            print(f"方式1成功: 直接用字符串查询")
        
        # 2. 如果是有效的ObjectId，尝试ObjectId形式
        if not doctor and ObjectId.is_valid(user_id):
            try:
                doctor = mongo.db.doctors.find_one({'userId': ObjectId(user_id)})
                if doctor:
                    print(f"方式2成功: 将userId转换为ObjectId查询")
            except Exception as e:
                print(f"ObjectId查询出错: {e}")
        
        # 3. 如果userId存储为字符串，但传入的是ObjectId形式的字符串
        if not doctor and ObjectId.is_valid(user_id):
            doctor = mongo.db.doctors.find_one({'userId': str(ObjectId(user_id))})
            if doctor:
                print(f"方式3成功: 查询字符串形式的ObjectId")
        
        # 如果找到了医生
        if doctor:
            print(f"找到医生: {doctor.get('name')}")
            normalized_doctor = normalize_data(doctor)
            
            # 获取科室名称
            department_name = ''
            if 'departmentId' in doctor:
                dept_id = doctor['departmentId']
                if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
                    dept_id = ObjectId(dept_id)
                department = mongo.db.departments.find_one({'_id': dept_id})
                if department:
                    department_name = department.get('name', '')
            normalized_doctor['departmentName'] = department_name
            
            print(f"=== 通过userId查询医生结束，已找到医生 ===")
            return jsonify({
                'success': True,
                'data': {
                    'total': 1,
                    'page': 1,
                    'limit': 1,
                    'doctors': [normalized_doctor]
                }
            }), 200
        else:
            print(f"=== 通过userId查询医生结束，未找到医生 ===")
            # 如果找不到医生，返回空结果
            return jsonify({
                'success': True,
                'data': {
                    'total': 0,
                    'page': 1,
                    'limit': 20,
                    'doctors': []
                }
            }), 200
    
    # 确定排序
    sort_direction = 1 if order.lower() == 'asc' else -1
    
    # 获取数据
    doctors_cursor = mongo.db.doctors.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(doctors_cursor, page, limit)
    
    # 标准化数据并添加科室信息
    doctors = []
    for doctor in paginated_data['items']:
        normalized_doctor = normalize_data(doctor)
        
        # 获取科室信息
        department_name = ''
        if 'departmentId' in doctor:
            dept_id = doctor['departmentId']
            if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
                dept_id = ObjectId(dept_id)
            department = mongo.db.departments.find_one({'_id': dept_id})
            if department:
                department_name = department.get('name', '')
        normalized_doctor['departmentName'] = department_name
        
        doctors.append(normalized_doctor)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'doctors': doctors
        }
    }), 200

@api_bp.route('/doctors', methods=['POST'])
@jwt_required()
@permission_required('doctor:create')
def create_doctor():
    """创建新医生"""
    # 验证请求数据
    schema = DoctorSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 验证科室是否存在
    department_id = data.get('departmentId')
    if not mongo.db.departments.find_one({'_id': ObjectId(department_id)}):
        return jsonify({
            'success': False,
            'message': '科室不存在'
        }), 400
    
    # 检查工号是否已存在
    if mongo.db.doctors.find_one({'staffId': data['staffId']}):
        return jsonify({
            'success': False,
            'message': '该工号已存在'
        }), 400
    
    # 检查是否关联用户
    user_id = data.get('userId')
    created_user = False
    user_details = None
    
    if user_id:
        # 检查关联的用户是否存在
        if not mongo.db.users.find_one({'_id': ObjectId(user_id)}):
            return jsonify({
                'success': False,
                'message': '关联的用户不存在'
            }), 400
    else:
        # 如果没有关联用户，自动创建一个对应的用户
        logger.info(f"医生 {data['name']} 没有关联用户，准备创建用户")
        user_result = create_user_for_doctor(data)
        
        if user_result:
            user_id = user_result['userId']
            data['userId'] = user_id  # 更新医生数据中的userId字段
            created_user = True
            user_details = {
                'id': str(user_id),
                'username': user_result['username'],
                'defaultPassword': user_result['password'],
                'message': '已自动创建用户账号'
            }
            logger.info(f"已为医生 {data['name']} 创建用户 {user_result['username']}")
        else:
            logger.warning(f"为医生 {data['name']} 创建用户失败")
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    
    # 保存到数据库
    result = mongo.db.doctors.insert_one(data)
    
    response_data = {
        'id': str(result.inserted_id),
        'staffId': data['staffId'],
        'name': data['name'],
        'createdAt': now.isoformat()
    }
    
    # 如果创建了用户，添加到响应中
    if created_user and user_details:
        response_data['user'] = user_details
    
    return jsonify({
        'success': True,
        'message': '医生创建成功',
        'data': response_data
    }), 201

@api_bp.route('/doctors/<id>', methods=['GET'])
@jwt_required()
@permission_required('doctor:read')
def get_doctor(id):
    """获取单个医生详情"""
    # 尝试按ID查找
    doctor = None
    
    # 如果是有效的ObjectId，按_id查找
    if ObjectId.is_valid(id):
        doctor = mongo.db.doctors.find_one({'_id': ObjectId(id)})
    
    # 如果没找到，尝试按staffId查找
    if not doctor:
        doctor = mongo.db.doctors.find_one({'staffId': id})
    
    if not doctor:
        return jsonify({
            'success': False,
            'message': '医生不存在'
        }), 404
    
    # 标准化数据
    normalized_doctor = normalize_data(doctor)
    
    # 获取科室信息
    department_info = None
    if 'departmentId' in doctor:
        dept_id = doctor['departmentId']
        if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
            dept_id = ObjectId(dept_id)
        department = mongo.db.departments.find_one({'_id': dept_id})
        if department:
            department_info = {
                'id': str(department['_id']),
                'name': department.get('name', ''),
                'location': department.get('location', '')
            }
    normalized_doctor['departmentInfo'] = department_info
    
    # 获取用户信息
    user_info = None
    if 'userId' in doctor and doctor['userId']:
        user_id = doctor['userId']
        if isinstance(user_id, str) and ObjectId.is_valid(user_id):
            user_id = ObjectId(user_id)
        user = mongo.db.users.find_one({'_id': user_id})
        if user:
            user_info = {
                'id': str(user['_id']),
                'username': user.get('username', ''),
                'email': user.get('email', ''),
                'role': user.get('role', '')
            }
    normalized_doctor['userInfo'] = user_info
    
    # 获取排班信息
    schedules = []
    today = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
    one_month_later = today + datetime.timedelta(days=30)
    
    doctor_schedules = mongo.db.schedules.find({
        'doctorId': str(doctor['_id']),
        'date': {'$gte': today, '$lte': one_month_later},
        'status': '正常'
    }).sort('date', 1)
    
    for schedule in doctor_schedules:
        schedules.append(normalize_data(schedule))
    
    normalized_doctor['schedules'] = schedules
    
    return jsonify({
        'success': True,
        'data': normalized_doctor
    }), 200

@api_bp.route('/doctors/<id>', methods=['PUT'])
@jwt_required()
@permission_required('doctor:update')
def update_doctor(id):
    """更新医生信息"""
    # 验证请求数据
    schema = DoctorUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 查找医生
    doctor = None
    if ObjectId.is_valid(id):
        doctor = mongo.db.doctors.find_one({'_id': ObjectId(id)})
    
    if not doctor:
        doctor = mongo.db.doctors.find_one({'staffId': id})
    
    if not doctor:
        return jsonify({
            'success': False,
            'message': '医生不存在'
        }), 404
    
    # 如果更新科室，验证科室是否存在
    if 'departmentId' in data:
        department_id = data['departmentId']
        if not mongo.db.departments.find_one({'_id': ObjectId(department_id)}):
            return jsonify({
                'success': False,
                'message': '科室不存在'
            }), 400
    
    # 准备更新数据
    update_data = data.copy()
    update_data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    result = mongo.db.doctors.update_one(
        {'_id': doctor['_id']},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '医生信息更新失败'
        }), 500
    
    # 如果医生有关联用户，同步更新用户信息
    if 'userId' in doctor and doctor['userId']:
        user_id = doctor['userId']
        user_update = {}
        
        # 同步需要更新的用户字段
        if 'name' in data:
            user_update['name'] = data['name']
        
        if 'contactInfo' in data:
            if 'email' in data['contactInfo']:
                user_update['email'] = data['contactInfo']['email']
            if 'phone' in data['contactInfo']:
                user_update['phone'] = data['contactInfo']['phone']
        
        if 'departmentId' in data:
            user_update['departmentId'] = data['departmentId']
        
        if 'title' in data or 'gender' in data or 'specialties' in data:
            # 获取当前用户信息
            user = mongo.db.users.find_one({'_id': ObjectId(user_id)})
            if user:
                personal_info = user.get('personalInfo', {})
                
                if 'title' in data:
                    personal_info['title'] = data['title']
                if 'gender' in data:
                    personal_info['gender'] = data['gender']
                if 'specialties' in data:
                    personal_info['specialties'] = data['specialties']
                
                user_update['personalInfo'] = personal_info
        
        if user_update:
            user_update['updatedAt'] = update_data['updatedAt']
            try:
                mongo.db.users.update_one(
                    {'_id': ObjectId(user_id)},
                    {'$set': user_update}
                )
                print(f"已同步更新医生 {doctor.get('name')} 的用户信息")
            except Exception as e:
                print(f"更新用户信息失败: {str(e)}")
    
    return jsonify({
        'success': True,
        'message': '医生信息更新成功',
        'data': {
            'id': str(doctor['_id']),
            'name': update_data.get('name', doctor.get('name')),
            'updatedAt': update_data['updatedAt'].isoformat()
        }
    }), 200

@api_bp.route('/doctors/<id>', methods=['DELETE'])
@jwt_required()
@permission_required('doctor:delete')
def delete_doctor(id):
    """删除医生（或标记为离职）"""
    # 查找医生
    doctor = None
    if ObjectId.is_valid(id):
        doctor = mongo.db.doctors.find_one({'_id': ObjectId(id)})
    
    if not doctor:
        doctor = mongo.db.doctors.find_one({'staffId': id})
    
    if not doctor:
        return jsonify({
            'success': False,
            'message': '医生不存在'
        }), 404
    
    # 检查医生是否有关联的医疗记录
    has_records = mongo.db.medical_records.find_one({'doctorId': str(doctor['_id'])})
    
    # 获取关联的用户ID
    user_id = doctor.get('userId')
    
    # 如果有关联记录，只将医生标记为离职
    if has_records:
        result = mongo.db.doctors.update_one(
            {'_id': doctor['_id']},
            {
                '$set': {
                    'status': '离职',
                    'updatedAt': datetime.datetime.utcnow()
                }
            }
        )
        
        if result.modified_count == 0:
            return jsonify({
                'success': False,
                'message': '医生状态更新失败'
            }), 500
        
        # 同时更新关联用户状态为inactive
        if user_id:
            try:
                mongo.db.users.update_one(
                    {'_id': ObjectId(user_id)},
                    {
                        '$set': {
                            'status': 'inactive',
                            'updatedAt': datetime.datetime.utcnow()
                        }
                    }
                )
                print(f"已将医生 {doctor.get('name')} 关联的用户标记为inactive")
            except Exception as e:
                print(f"更新用户状态失败: {str(e)}")
        
        return jsonify({
            'success': True,
            'message': '医生已标记为离职',
            'data': None
        }), 200
    
    # 如果没有关联记录，可以真正删除
    result = mongo.db.doctors.delete_one({'_id': doctor['_id']})
    
    if result.deleted_count == 0:
        return jsonify({
            'success': False,
            'message': '医生删除失败'
        }), 500
    
    # 同时删除关联的用户账号，或标记为已删除
    if user_id:
        try:
            # 检查用户是否有其他关联记录
            has_other_records = False
            
            # 如果没有其他关联记录，可以删除用户
            if not has_other_records:
                mongo.db.users.delete_one({'_id': ObjectId(user_id)})
                print(f"已删除医生 {doctor.get('name')} 关联的用户")
            else:
                # 如果有其他关联，只标记为deleted
                mongo.db.users.update_one(
                    {'_id': ObjectId(user_id)},
                    {
                        '$set': {
                            'status': 'deleted',
                            'updatedAt': datetime.datetime.utcnow()
                        }
                    }
                )
                print(f"已将医生 {doctor.get('name')} 关联的用户标记为deleted")
        except Exception as e:
            print(f"处理用户删除失败: {str(e)}")
    
    return jsonify({
        'success': True,
        'message': '医生删除成功',
        'data': None
    }), 200

@api_bp.route('/doctors/<id>/schedules', methods=['GET'])
@jwt_required()
def get_doctor_schedules(id):
    """获取医生排班信息"""
    # 查找医生
    doctor = None
    if ObjectId.is_valid(id):
        doctor = mongo.db.doctors.find_one({'_id': ObjectId(id)})
    
    if not doctor:
        doctor = mongo.db.doctors.find_one({'staffId': id})
    
    if not doctor:
        return jsonify({
            'success': False,
            'message': '医生不存在'
        }), 404
    
    # 获取查询参数
    start_date = request.args.get('startDate')
    if start_date:
        try:
            start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
        except ValueError:
            start_date = None
    else:
        start_date = None
    
    end_date = request.args.get('endDate')
    if end_date:
        try:
            end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
        except ValueError:
            end_date = None
    else:
        end_date = None
    
    # 构建查询条件
    query = {'doctorId': str(doctor['_id'])}
    
    # 只有在提供了日期范围时才添加日期筛选
    if start_date and end_date:
        query['date'] = {'$gte': start_date, '$lte': end_date}
    elif start_date:
        query['date'] = {'$gte': start_date}
    elif end_date:
        query['date'] = {'$lte': end_date}
    
    # 查询排班 - 按日期倒序排列（从最近到最早）
    schedules = mongo.db.schedules.find(query).sort('date', -1)
    
    # 标准化数据
    normalized_schedules = [normalize_data(schedule) for schedule in schedules]
    
    return jsonify({
        'success': True,
        'data': {
            'doctorInfo': {
                'id': str(doctor['_id']),
                'staffId': doctor['staffId'],
                'name': doctor['name'],
                'title': doctor.get('title', '')
            },
            'schedules': normalized_schedules
        }
    }), 200

@api_bp.route('/doctors/by-user/<user_id>', methods=['GET'])
@jwt_required()
@permission_required('doctor:read')
def get_doctor_by_user(user_id):
    """通过用户ID获取医生信息"""
    logger.info(f"通过用户ID获取医生信息: {user_id}")
    
    doctor = None
    
    # 尝试不同的查询方式找到医生信息
    try:
        # 1. 如果是有效的ObjectId，尝试使用ObjectId形式
        if ObjectId.is_valid(user_id):
            doctor = mongo.db.doctors.find_one({'userId': ObjectId(user_id)})
            if doctor:
                logger.info(f"使用ObjectId形式找到医生: {doctor.get('name')}")
        
        # 2. 尝试字符串形式
        if not doctor:
            doctor = mongo.db.doctors.find_one({'userId': user_id})
            if doctor:
                logger.info(f"使用字符串形式找到医生: {doctor.get('name')}")
        
        # 3. 如果用户ID是有效的ObjectId，尝试字符串形式的ObjectId
        if not doctor and ObjectId.is_valid(user_id):
            doctor = mongo.db.doctors.find_one({'userId': str(ObjectId(user_id))})
            if doctor:
                logger.info(f"使用字符串形式的ObjectId找到医生: {doctor.get('name')}")
        
        # 4. 最后尝试使用staffId查询
        if not doctor:
            user = mongo.db.users.find_one({'_id': ObjectId(user_id) if ObjectId.is_valid(user_id) else user_id})
            if user and 'staffId' in user:
                doctor = mongo.db.doctors.find_one({'staffId': user['staffId']})
                if doctor:
                    logger.info(f"通过用户的staffId找到医生: {doctor.get('name')}")
    except Exception as e:
        logger.error(f"查询医生时发生错误: {str(e)}")
    
    # 如果没有找到医生
    if not doctor:
        logger.warning(f"未找到与用户ID {user_id} 关联的医生")
        return jsonify({
            'success': False,
            'message': '未找到与该用户关联的医生'
        }), 404
    
    try:
        # 标准化数据
        normalized_doctor = normalize_data(doctor)
        
        # 获取科室信息
        department_info = None
        if 'departmentId' in doctor and doctor['departmentId']:
            dept_id = doctor['departmentId']
            if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
                dept_id = ObjectId(dept_id)
            department = mongo.db.departments.find_one({'_id': dept_id})
            if department:
                department_info = {
                    'id': str(department['_id']),
                    'name': department.get('name', ''),
                    'location': department.get('location', '')
                }
        normalized_doctor['departmentInfo'] = department_info
        
        # 获取用户信息
        user_info = None
        if 'userId' in doctor and doctor['userId']:
            user_id_for_query = doctor['userId']
            if isinstance(user_id_for_query, str) and ObjectId.is_valid(user_id_for_query):
                user_id_for_query = ObjectId(user_id_for_query)
            user = mongo.db.users.find_one({'_id': user_id_for_query})
            if user:
                user_info = {
                    'id': str(user['_id']),
                    'username': user.get('username', ''),
                    'email': user.get('email', ''),
                    'role': user.get('role', '')
                }
        normalized_doctor['userInfo'] = user_info
        
        logger.info(f"成功返回医生信息: {normalized_doctor.get('name')}")
        
        return jsonify({
            'success': True,
            'data': normalized_doctor
        }), 200
    except Exception as e:
        logger.error(f"处理医生数据时发生错误: {str(e)}")
        return jsonify({
            'success': False,
            'message': f'处理医生数据时发生错误: {str(e)}'
        }), 500

def create_user_for_doctor(doctor_data):
    """为医生创建对应的用户账号"""
    try:
        # 生成用户名，基于医生的staffId
        username = f"doc_{doctor_data['staffId'].lower()}"
        
        # 检查用户名是否已存在，如果存在则添加随机后缀
        while mongo.db.users.find_one({'username': username}):
            username = f"doc_{doctor_data['staffId'].lower()}_{random.randint(1000, 9999)}"
        
        # 生成默认密码（可以是医生工号等）
        default_password = doctor_data['staffId']
        
        # 创建用户记录
        user_data = {
            'username': username,
            'password': hash_password(default_password),
            'name': doctor_data['name'],
            'email': doctor_data.get('contactInfo', {}).get('email', f"{username}@hospital.com"),
            'phone': doctor_data.get('contactInfo', {}).get('phone', ''),
            'role': 'doctor',
            'staffId': doctor_data['staffId'],
            'status': 'active',
            'departmentId': doctor_data.get('departmentId'),
            'createdAt': datetime.datetime.utcnow(),
            'updatedAt': datetime.datetime.utcnow(),
            'lastLogin': None,
            'personalInfo': {
                'gender': doctor_data.get('gender', ''),
                'title': doctor_data.get('title', ''),
                'specialties': doctor_data.get('specialties', [])
            }
        }
        
        # 保存用户记录到数据库
        user_result = mongo.db.users.insert_one(user_data)
        
        logger.info(f"为医生 {doctor_data['name']} 自动创建用户: {username}")
        
        return {
            'userId': user_result.inserted_id, 
            'username': username, 
            'password': default_password
        }
    except Exception as e:
        logger.error(f"为医生创建用户时出错: {str(e)}")
        return None 